home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 4
/
Meeting Pearls Vol. IV (1996)(GTI - Schatztruhe)[!].iso
/
Pearls
/
dev
/
Oberon
/
OberonV4
/
system
/
StyleElems.Mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1990-01-01
|
11KB
|
258 lines
Syntax10.Scn.Fnt
Syntax10b.Scn.Fnt
Syntax12.Scn.Fnt
Syntax10i.Scn.Fnt
MODULE StyleElems; (** CAS 19-May-92 / 28-Sep-93 **)
IMPORT
Display, Files, Fonts, Viewers, Texts, Oberon, MenuViewers, TextFrames, ParcElems;
CONST
search* = 0; change* = 1; rename* = 2;
NameFont = "Syntax8.Scn.Fnt";
rightKey = 0; middleKey = 1; leftKey = 2; cancel = {rightKey, middleKey, leftKey};
pageBreak = TextFrames.pageBreak;
unit = TextFrames.Unit;
TYPE
Name* = ARRAY 32 OF CHAR;
Parc* = POINTER TO ParcDesc;
ParcDesc* = RECORD (TextFrames.ParcDesc)
name*: Name;
home: Texts.Text
END;
UpdateMsg* = RECORD (Texts.ElemMsg)
id*: INTEGER;
pos*: LONGINT;
name*, newName*: Name;
parc*: Parc
END;
font*: Fonts.Font;
(* arguments *)
PROCEDURE MarkedFrame (): TextFrames.Frame;
VAR v: Viewers.Viewer;
BEGIN v := Oberon.MarkedViewer();
IF (v IS MenuViewers.Viewer) & (v.dsc.next IS TextFrames.Frame) THEN
RETURN v.dsc.next(TextFrames.Frame)
ELSE RETURN NIL
END
END MarkedFrame;
PROCEDURE FocusFrame (): TextFrames.Frame;
VAR v: Viewers.Viewer; f: TextFrames.Frame;
BEGIN v := Oberon.FocusViewer;
IF (v IS MenuViewers.Viewer) & (v.dsc.next IS TextFrames.Frame) THEN
f := v.dsc.next(TextFrames.Frame);
IF f.hasCar THEN RETURN f ELSE RETURN NIL END
ELSE RETURN NIL
END
END FocusFrame;
PROCEDURE GetMainArg (VAR S: Texts.Scanner);
(*after command or (^) at selection*)
VAR text: Texts.Text; beg, end, time: LONGINT;
BEGIN Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c = "^") THEN Oberon.GetSelection(text, beg, end, time);
IF time >= 0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END
END;
IF S.line # 0 THEN S.class := Texts.Inval END
END GetMainArg;
(* portable I/O *)
PROCEDURE WriteString (VAR r: Files.Rider; s: ARRAY OF CHAR);
VAR i: INTEGER;
BEGIN i := 0;
WHILE s[i] # 0X DO INC(i) END;
Files.WriteBytes(r, s, i + 1)
END WriteString;
PROCEDURE ReadString (VAR r: Files.Rider; VAR s: ARRAY OF CHAR);
VAR i: INTEGER; ch: CHAR;
BEGIN i := 0;
REPEAT Files.Read(r, ch); s[i] := ch; INC(i) UNTIL (ch = 0X) OR (i = LEN(s));
IF ch # 0X THEN s[0] := 0X END
END ReadString;
(** operations on elements **)
PROCEDURE Broadcast* (T: Texts.Text; VAR msg: UpdateMsg);
VAR R: Texts.Reader; e: Texts.Elem;
BEGIN Texts.OpenReader(R, T, 0); Texts.ReadElem(R);
WHILE ~R.eot DO e := R.elem; msg.pos := Texts.Pos(R) - 1; Texts.ReadElem(R); e.handle(e, msg) END
END Broadcast;
PROCEDURE Search* (T: Texts.Text; VAR name: Name; VAR P: Parc);
VAR update: UpdateMsg;
BEGIN update.id := search; update.name := name; update.parc := NIL;
Broadcast(T, update);
P := update.parc
END Search;
PROCEDURE Synch* (P: Parc; VAR synched: BOOLEAN);
VAR T: Texts.Text; Q: Parc;
BEGIN T := Texts.ElemBase(P); synched := FALSE;
IF (T # NIL) & (P.home # T) THEN Search(T, P.name, Q);
IF Q # NIL THEN ParcElems.CopyParc(Q, P); EXCL(P.opts, pageBreak); synched := TRUE END;
P.home := T
END
END Synch;
PROCEDURE ChangeSetting* (P: Parc);
VAR T: Texts.Text; update: UpdateMsg;
BEGIN T := Texts.ElemBase(P);
update.id := change; update.name := P.name; update.parc := P;
Broadcast(T, update)
END ChangeSetting;
PROCEDURE ChangeName* (P: Parc; name: ARRAY OF CHAR; VAR synched: BOOLEAN);
BEGIN synched := FALSE;
IF P.name # name THEN COPY(name, P.name); P.home := NIL; Synch(P, synched) END
END ChangeName;
PROCEDURE Load* (P: Parc; VAR r: Files.Rider);
BEGIN ParcElems.LoadParc(P, r); ReadString(r, P.name); P.home := Texts.ElemBase(P)
END Load;
PROCEDURE Store* (P: Parc; VAR r: Files.Rider);
VAR synched: BOOLEAN;
BEGIN Synch(P, synched); ParcElems.StoreParc(P, r); WriteString(r, P.name)
END Store;
PROCEDURE Copy* (SP, DP: Parc);
BEGIN ParcElems.CopyParc(SP, DP); DP.name := SP.name; DP.home := SP.home
END Copy;
PROCEDURE Prepare* (P: Parc; indent, unit: LONGINT);
VAR synched: BOOLEAN;
BEGIN Synch(P, synched); ParcElems.Prepare(P, indent, unit);
IF LONG(font.height + 4) * unit > P.H THEN P.H := LONG(font.height + 4) * unit END
END Prepare;
PROCEDURE Width (P: Parc): INTEGER;
VAR pat: Display.Pattern; i, px, dx, x, y, w, h: INTEGER;
BEGIN i := 0; px := 0;
WHILE P.name[i] # 0X DO
Display.GetChar(font.raster, P.name[i], dx, x, y, w, h, pat); INC(px, dx); INC(i)
END;
RETURN px
END Width;
PROCEDURE DrawString (P: Parc; col: SHORTINT; x0, y0, bw: INTEGER);
VAR pat: Display.Pattern; i, dx, x, y, w, h: INTEGER;
BEGIN i := 0;
Display.ReplConst(Display.black, x0, y0, bw + 4, font.height, Display.replace); INC(x0, 2); DEC(y0, font.minY);
WHILE P.name[i] # 0X DO
Display.GetChar(font.raster, P.name[i], dx, x, y, w, h, pat); INC(i);
Display.CopyPattern(col, pat, x0 + x, y0 + y, Display.replace); INC(x0, dx)
END
END DrawString;
PROCEDURE Draw* (P: Parc; F: Display.Frame; col: SHORTINT; x0, y0: INTEGER);
VAR bw: INTEGER;
BEGIN ParcElems.Draw(P, F, col, x0, y0);
bw := Width(P); DrawString(P, col, x0 + SHORT(P.W DIV unit) - bw - 20, y0 + 4, bw)
END Draw;
PROCEDURE Edit* (P: Parc; F: TextFrames.Frame; pos: LONGINT; x0, y0, x, y: INTEGER; keysum: SET);
BEGIN
IF F.showsParcs THEN ParcElems.Edit(P, F, pos, x0, y0, x, y, keysum);
IF (middleKey IN keysum) & (keysum # cancel) THEN ChangeSetting(P) END
END
END Edit;
PROCEDURE SetAttr* (P: Parc; F: TextFrames.Frame; VAR S: Texts.Scanner; log: Texts.Text);
BEGIN ParcElems.SetAttr(P, F, unit, S, log); ChangeSetting(P)
END SetAttr;
(** handle elements **)
PROCEDURE Handle* (E: Texts.Elem; VAR msg: Texts.ElemMsg);
VAR e: Parc; opts: SET; synched: BOOLEAN;
BEGIN
WITH E: Parc DO
IF msg IS TextFrames.DisplayMsg THEN
WITH msg: TextFrames.DisplayMsg DO
IF msg.prepare THEN Prepare(E, msg.indent, unit)
ELSE Draw(E, msg.frame, msg.col, msg.X0, msg.Y0)
END
END
ELSIF msg IS Texts.IdentifyMsg THEN
WITH msg: Texts.IdentifyMsg DO msg.mod := "StyleElems"; msg.proc := "Alloc" END
ELSIF msg IS Texts.FileMsg THEN
WITH msg: Texts.FileMsg DO
IF msg.id = Texts.load THEN Load(E, msg.r)
ELSIF msg.id = Texts.store THEN Store(E, msg.r)
END
END
ELSIF msg IS Texts.CopyMsg THEN NEW(e); Copy(E, e); msg(Texts.CopyMsg).e := e
ELSIF msg IS TextFrames.TrackMsg THEN
WITH msg: TextFrames.TrackMsg DO
Edit(E, msg.frame(TextFrames.Frame), msg.pos, msg.X0, msg.Y0, msg.X, msg.Y, msg.keys)
END
ELSIF msg IS ParcElems.StateMsg THEN
WITH msg: ParcElems.StateMsg DO
IF msg.id = ParcElems.set THEN SetAttr(E, msg.frame, msg.par, msg.log)
ELSE ParcElems.Handle(E, msg)
END
END
ELSIF msg IS UpdateMsg THEN
WITH msg: UpdateMsg DO
IF (msg.id = search) & (msg.parc = NIL) & (E.name = msg.name) & (E.home = Texts.ElemBase(E)) THEN
msg.parc := E
ELSIF (msg.id = change) & (E.name = msg.name) THEN
IF E # msg.parc THEN opts := E.opts;
ParcElems.CopyParc(msg.parc, E); E.opts := E.opts - {pageBreak} + opts * {pageBreak}
END;
ParcElems.ChangedParc(E, msg.pos)
ELSIF (msg.id = rename) & (E.name = msg.name) THEN
ChangeName(E, msg.newName, synched);
IF synched THEN ParcElems.ChangedParc(E, msg.pos)
ELSE Texts.ChangeLooks(Texts.ElemBase(E), msg.pos, msg.pos+1, {}, NIL, 0, 0)
END
END
END
ELSE ParcElems.Handle(E, msg)
END
END
END Handle;
PROCEDURE Alloc*;
VAR p: Parc;
BEGIN NEW(p); p.handle := Handle; Texts.new := p
END Alloc;
(** commands **)
PROCEDURE Insert*; (** ("^" | name | string) **)
VAR F: TextFrames.Frame; P: TextFrames.Parc; p: Parc; S: Texts.Scanner; pbeg: LONGINT;
m: TextFrames.InsertElemMsg;
BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN
F := FocusFrame();
IF F # NIL THEN TextFrames.ParcBefore(F.text, F.carloc.pos, P, pbeg)
ELSE P := TextFrames.defParc
END;
NEW(p); ParcElems.CopyParc(P, p);
p.handle := Handle; COPY(S.s, p.name); p.home := NIL; m.e := p;
Oberon.FocusViewer.handle(Oberon.FocusViewer, m)
END
END Insert;
PROCEDURE Rename*; (** ("^" | name | string) ["/s"] **)
VAR S: Texts.Scanner; F: TextFrames.Frame; P: TextFrames.Parc; p: Parc;
pbeg: LONGINT; synch, synched: BOOLEAN;
name: Name;
BEGIN F := MarkedFrame(); Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
IF (F # NIL) & F.hasSel & (F.selbeg.pos + 1 = F.selend.pos)
& ((S.class = Texts.Name) OR (S.class = Texts.String)) THEN
TextFrames.ParcBefore(F.text, F.selbeg.pos, P, pbeg);
IF (P IS Parc) & (pbeg = F.selbeg.pos) & (P(Parc).name # S.s) THEN
COPY(S.s, name); Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c = "/") & (CAP(S.nextCh) = "S") THEN synch := TRUE
ELSE Search(F.text, name, p); synch := p = NIL
END;
ChangeName(P(Parc), name, synched);
IF synched THEN ParcElems.ChangedParc(P, pbeg)
ELSE Texts.ChangeLooks(F.text, pbeg, pbeg+1, {}, NIL, 0, 0)
END
END
END
END Rename;
PROCEDURE RenameAll*; (** ("^" | name | string) ["/s"] **)
VAR S: Texts.Scanner; F: TextFrames.Frame; P: TextFrames.Parc; p: Parc;
pbeg: LONGINT; synch: BOOLEAN;
msg: UpdateMsg; name: Name;
BEGIN F := MarkedFrame(); Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); GetMainArg(S);
IF (F # NIL) & F.hasSel & (F.selbeg.pos + 1 = F.selend.pos)
& ((S.class = Texts.Name) OR (S.class = Texts.String)) THEN
TextFrames.ParcBefore(F.text, F.selbeg.pos, P, pbeg);
IF (P IS Parc) & (pbeg = F.selbeg.pos) & (P(Parc).name # S.s) THEN
COPY(S.s, name); Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c = "/") & (CAP(S.nextCh) = "S") THEN synch := TRUE
ELSE Search(F.text, name, p); synch := p = NIL
END;
IF synch THEN
msg.id := rename; msg.name := P(Parc).name; msg.newName := name;
Broadcast(F.text, msg)
END
END
END
END RenameAll;
BEGIN font := Fonts.This(NameFont)
END StyleElems.
Write.Open ^ Styles.Text System.Free StyleElems ~
StyleElems.Insert ^ StyleElems.Rename ^ StyleElems.RenameAll ^
"heading" "sub-heading" "table A"/s